import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import paskal.abstractplayer.Playlist;
import paskal.abstractplayer.VkTrack;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class Grabber {

	private static String accessToken = "";
	private static String apiURL = "https://api.vk.com/method/";

	private static void init() {
		try {
			URLConnection urlConn = new URL(
					"http://relax.cloudfoundry.com/main/accessToken")
					.openConnection();
			int avaibleBytes = urlConn.getInputStream().available();
			byte[] bytes = new byte[avaibleBytes];
			urlConn.getInputStream().read(bytes);
			accessToken = new String(bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Playlist search(String query) {
		File file = new File(query);
		if (file.exists()) {
			if (file.isFile())
				return openFolder(file.getParent(), file);
			else
				return openFolder(query, null);
		}

		if (accessToken.isEmpty()) {
			init();
		}

		Map<String, String> params = new HashMap<String, String>();
		params.put("q", query);
		params.put("count", "73");
		JsonElement json = new JsonParser()
				.parse(vkApi("audio.search", params));
		JsonArray array = json.getAsJsonObject().getAsJsonArray("response");
		Iterator<JsonElement> iterator = array.iterator();
		iterator.next();
		List<VkTrack> playlist = new ArrayList<VkTrack>();
		while (iterator.hasNext()) {
			JsonObject e = iterator.next().getAsJsonObject();
			VkTrack track = new VkTrack();
			track.setAid(e.getAsJsonPrimitive("aid").getAsString());
			track.setDuration(e.getAsJsonPrimitive("duration").getAsInt());
			if (e.getAsJsonPrimitive("lyrics_id") != null) {
				track.setLyricsId(e.getAsJsonPrimitive("lyrics_id")
						.getAsString());
			}
			track.setOwnerId(e.getAsJsonPrimitive("owner_id").getAsString());
			track.setTitle(e.getAsJsonPrimitive("artist").getAsString()
					+ e.getAsJsonPrimitive("title").getAsString());
			String temp = e.getAsJsonPrimitive("url").getAsString();
			track.setUrl(temp);
			track.setExtention(temp.substring(temp.lastIndexOf('.') + 1,
					temp.length()));

			playlist.add(track);
		}
		return new Playlist(playlist);
	}

	public static String getLyrics(String id) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("lyrics_id", id);

		JsonElement json = new JsonParser().parse(vkApi("audio.getLyrics",
				params));

		String temp = json.getAsJsonObject().getAsJsonObject("response")
				.getAsJsonPrimitive("text").getAsString();
		return temp;
	}

	private static String vkApi(String method, Map<String, String> params) {
		if (params == null)
			params = new HashMap<String, String>();
		params.put("access_token", accessToken);
		StringBuilder urlString = new StringBuilder(method + '?');
		for (String key : params.keySet()) {
			try {
				urlString
						.append(key)
						.append('=')
						.append(java.net.URLEncoder.encode(params.get(key),
								"utf-8")).append('&');
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		urlString.deleteCharAt(urlString.length() - 1);
		try {
			URLConnection urlConn = new URL(apiURL + urlString)
					.openConnection();

			InputStream in = urlConn.getInputStream();
			ByteArrayOutputStream bytes = new ByteArrayOutputStream();
			int i = 0;
			while ((i = in.read()) != -1) {
				bytes.write(i);
			}
			in.close();
			bytes.close();
			return new String(bytes.toByteArray(), "utf-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	public static Playlist openFolder(String path, File file) {
		List<VkTrack> playlist = new ArrayList<VkTrack>();
		int active = 0;

		if ((file != null) && (file.exists())) {
			if (file.getName().endsWith("pls")) {
				return parsePLS(file);
			} else if (file.getName().endsWith("m3u")) {
				return parseM3U(file);
			}
		}

		File dir = new File(path);
		File[] files = dir.listFiles();
		for (File f : files) {
			if (f.getName().endsWith("mp3") || f.getName().endsWith("wav")
					|| f.getName().endsWith("ogg")
					|| f.getName().endsWith("spx")
					|| f.getName().endsWith("flac")) {
				VkTrack track = new VkTrack();
				track.setDuration(0);
				track.setTitle(f.getName().substring(0,
						f.getName().length() - 4));
				track.setFilePath(f.getPath());
				track.setExtention(f.getName().substring(
						f.getName().lastIndexOf('.') + 1));
				if (f.equals(file)) {
					active = playlist.size();
				}
				playlist.add(track);
			}
		}
		Playlist p = new Playlist(playlist);
		p.get(active);
		return p;
	}

	public static Playlist parsePLS(File file) {
		List<VkTrack> p = new ArrayList<VkTrack>();
		try {
			FileInputStream in = new FileInputStream(file);
			byte[] data = new byte[in.available()];
			in.read(data);
			in.close();

			StringBuilder sb = new StringBuilder(new String(data));
			sb.append('\n');

			if (sb.indexOf("[playlist]") == -1) {
				return new Playlist(p);
			}

			int temp0 = sb.indexOf("Version");
			int temp1 = sb.indexOf("=", temp0) + 1;

			if (Integer.parseInt(sb.substring(temp1, sb.indexOf("\n", temp1))
					.trim()) != 2) {
				return new Playlist(p);
			}

			temp0 = sb.indexOf("numberOfEntries");
			temp1 = sb.indexOf("=", temp0) + 1;
			int numberOfEntries = Integer.parseInt(sb.substring(temp1,
					sb.indexOf("\n", temp1)).trim());

			for (int i = 1; i <= numberOfEntries; i++) {
				VkTrack track = new VkTrack();
				temp0 = sb.indexOf("File" + i);
				temp1 = sb.indexOf("=", temp0) + 1;

				String temp = sb.substring(temp1, sb.indexOf("\n", temp1))
						.trim();
				File f = new File(temp);
				if (f.exists()) {
					track.setFilePath(f.getPath());
				} else {
					track.setUrl(temp);
				}

				if (temp.lastIndexOf('.') != -1) {
					track.setExtention(temp.substring(temp.lastIndexOf('.') + 1));
				}

				temp0 = sb.indexOf("Title" + i);
				temp1 = sb.indexOf("=", temp0) + 1;
				track.setTitle(sb.substring(temp1, sb.indexOf("\n", temp1))
						.trim());

				temp0 = sb.indexOf("Length" + i);
				temp1 = sb.indexOf("=", temp0) + 1;
				track.setDuration(Integer.parseInt(sb.substring(temp1,
						sb.indexOf("\n", temp1)).trim()));
				p.add(track);
			}
			return new Playlist(p);
		} catch (Exception e) {
			System.err.println("Not valid pls file:\n");
			e.printStackTrace();
		}

		return new Playlist(p);
	}

	public static Playlist parseM3U(File file) {
		List<VkTrack> p = new ArrayList<VkTrack>();
		try {
			FileInputStream in = new FileInputStream(file);
			byte[] data = new byte[in.available()];
			in.read(data);
			in.close();

			StringBuilder sb = new StringBuilder(new String(data));
			sb.append('\n');

			if (sb.indexOf("#EXTM3U") == -1) {
				int n0 = 0;
				int n = 0;
				while ((n = sb.indexOf("\n", n0)) != -1) {
					VkTrack track = new VkTrack();
					String temp = sb.substring(n0, n).trim();
					File f = new File(temp);
					if (f.exists()) {
						track.setFilePath(f.getPath());
						track.setTitle(f.getName());
					} else {
						track.setUrl(temp);
					}
					if (temp.lastIndexOf('.') != -1) {
						track.setExtention(temp.substring(temp.lastIndexOf('.') + 1));
					}
					p.add(track);
					n0 = n + 1;
				}
			} else {
				int n0 = 0;
				int n = 0;
				while ((n = sb.indexOf("#EXTINF:", n0)) != -1) {
					VkTrack track = new VkTrack();
					n0 = n + 8;
					n = sb.indexOf(",", n + 8);
					String temp = sb.substring(n0, n).trim();
					track.setDuration(Integer.parseInt(temp));
					n0 = n + 1;
					n = sb.indexOf("\n", n0);
					temp = sb.substring(n0, n).trim();
					track.setTitle(temp);
					n0 = n + 1;
					n = sb.indexOf("\n", n0);
					temp = sb.substring(n0, n).trim();

					File f = new File(temp);
					if (f.exists()) {
						track.setFilePath(f.getPath());
						track.setTitle(f.getName());
					} else {
						track.setUrl(temp);
					}
					if (temp.lastIndexOf('.') != -1) {
						track.setExtention(temp.substring(temp.lastIndexOf('.') + 1));
					}
					p.add(track);
					n0 = n + 1;
				}
			}
			return new Playlist(p);
		} catch (Exception e) {
			System.err.println("Not valid m3u file:\n");
			e.printStackTrace();
		}

		return new Playlist(p);
	}

	// public static void main(String[] args) {
	// parseM3U(new File("/home/paskal/bla.m3u"));
	// }
}